#include "detour_hook_function_ctrl.h"
#include "detours.h"

CDetourHookFunctionCtrl::CDetourHookFunctionCtrl()
{
	m_hModule = LoadLibrary("Ws2_32.dll");
}

CDetourHookFunctionCtrl::~CDetourHookFunctionCtrl()
{
	FreeLibrary(m_hModule);
}

void CDetourHookFunctionCtrl::AddHookFunc(const std::string& func_name, FARPROC hook_func)
{
	HookFunc hf_info;
	hf_info.m_old_func = (void*)GetProcAddress(m_hModule, func_name.c_str());
	hf_info.m_new_func = (void*)hook_func;

	m_hook_func_info.insert(make_pair(func_name, hf_info));
}

void CDetourHookFunctionCtrl::InitHook()
{
	DetourRestoreAfterWith();

	DetourTransactionBegin();
	DetourUpdateThread(GetCurrentThread());

	for (auto &item : m_hook_func_info)
	{
		const HookFunc& func = item.second;
		DetourAttach(&(PVOID&)func.m_old_func, func.m_new_func);
	}
	DetourTransactionCommit();
}

void CDetourHookFunctionCtrl::UninitHook()
{
	DetourRestoreAfterWith();

	DetourTransactionBegin();
	DetourUpdateThread(GetCurrentThread());

	for (auto &item : m_hook_func_info)
	{
		const HookFunc& func = item.second;
		DetourDetach(&(PVOID&)func.m_old_func, func.m_new_func);
	}

	DetourTransactionCommit();
}

FARPROC CDetourHookFunctionCtrl::GetSystemFunc(const std::string& func_name)
{
	auto iter = m_hook_func_info.find(func_name);
	if (iter != m_hook_func_info.end())
	{
		return (FARPROC)iter->second.m_old_func;
	}

	return NULL;
}
